/* Breakout JavaScript by Louis Watson */

var brickColors = 0;
var bricks = [
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,1,1,1,1,1,1,0,0],
  [0,2,2,2,2,2,2,2,2,0],
  [1,3,2,2,2,2,2,2,3,1],
  [1,3,3,3,4,4,3,3,3,1],
  [1,3,3,4,4,4,4,3,3,1],
  [1,3,3,3,4,4,3,3,3,1],              
  [0,1,1,2,2,2,2,1,1,0],
  [0,0,1,1,1,1,1,1,0,0]
]; // Brick Layout: 1 is orange, 2 is green, 3 is gray, 0 means no brick
var brickSize = [0, 12];
var ballDelta = [0, 0];
var ballLocation = [0, 0];
var ballRadius = 6;
var canvas; // this assigns the canvas element
var context; // this gets the 2D context from the canvas
var gameLoop;
var paddleDelta = [0, 0];
var paddleLocation = [0, 0];
var paddleMove;
var paddleSize = [100, 10];
var paddleSpeed = 10;
var score = 0;
var scoreHeight = 30;

function animate () {
  context.clearRect(0, 0, canvas.width, canvas.height);
  renderBricks();
  renderScore();
  moveBall();
  movePaddle();
  renderPaddle();
  renderBall();
}

function ballCollideX() {
  var bumpedX = false;	
  for (var i = 0; i < bricks.length; i++) {
    for (var j = 0; j < bricks[i].length; j++) {
      if (bricks[i][j] > 0) { // if brick is still visible
        var brick = [j * brickSize[0], i * brickSize[1]];
        if (((ballLocation[0] + ballDelta[0] + ballRadius >= brick[0]) &&
             (ballLocation[0] + ballRadius <= brick[0])) // barely touching from left
            || ((ballLocation[0] + ballDelta[0] - ballRadius <= brick[0] + brickSize[0]) &&
                (ballLocation[0] - ballRadius >= brick[0] + brickSize[0])) // barely touching from right
           ){		
          if ((ballLocation[1] + ballDelta[1] -ballRadius <= brick[1] + brickSize[1]) &&
              (ballLocation[1] + ballDelta[1] + ballRadius >= brick[1])) {													
            // weaken brick and increase score
            explodeBrick(i,j);
            bumpedX = true;
          }
        }
      }
    }
  }
  return bumpedX;
}

function ballCollideY() {
  var bumpedY = false;
  for (var i = 0; i < bricks.length; i++) {
    for (var j=0; j < bricks[i].length; j++) {
      if (bricks[i][j]){ // if brick is still visible
        var brick = [j * brickSize[0], i * brickSize[1]];
        if (
          // barely touching from below
          ((ballLocation[1] + ballDelta[1] - ballRadius <= brick[1] + brickSize[1]) && 
           (ballLocation[1] - ballRadius >= brick[1] + brickSize[1]))
          ||
          // barely touching from above
          ((ballLocation[1] + ballDelta[1] + ballRadius >= brick[1]) &&
           (ballLocation[1] + ballRadius <= brick[1] ))){
          if (ballLocation[0] + ballDelta[0] + ballRadius >= brick[0] && 
              ballLocation[0] + ballDelta[0] - ballRadius<= brick[0] + brickSize[0]){										
            // weaken brick and increase score
            explodeBrick(i, j);							
            bumpedY = true;
          }						
        }
      }
    }
  }
  return bumpedY;
}

function endGame(){
  clearInterval(gameLoop);
  context.fillText('The End!!!!', canvas.width / 2, canvas.height / 2);
}
        
function explodeBrick(i, j) {
  // First weaken the brick (0 means brick has gone)
  bricks[i][j] --;
  
  if (bricks[i][j]>0){ 
    // The brick is weakened but still around. Give a single point.
    score += 4;
  } else {
    // give player an extra point when the brick disappears
    score += 8;		
    // breakingSound.play();
  }
}

function getJQuery(callback) {
  // adding the script tag to the head as suggested before
  var head = document.getElementsByTagName('head')[0];
  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = 'http://code.jquery.com/jquery-1.7.2.min.js';
  // then bind the event to the callback function
  // there are several events for cross browser compatibility
  script.onreadystatechange = callback;
  script.onload = callback;
  // fire the loading
  head.appendChild(script);
}

function initVars() {
  paddleLocation[0] = (canvas.width - paddleSize[0]) / 2;
  paddleLocation[1] = canvas.height - scoreHeight - paddleSize[1];
  ballLocation[0] = canvas.width / 2;
  ballLocation[1] = paddleLocation[1] - (ballRadius + 1);
  brickSize[0] = canvas.width / bricks[0].length;
}

function moveBall(){
  // First check if we will bump into something
  
  // If top of the ball touches the top then reverse Y direction
  if (ballLocation[1] + ballDelta[1] - ballRadius < 0 || ballCollideY()){
    ballDelta[1] = -ballDelta[1];
    // bouncingSound.play();
  }
  
  // If the bottom of the ball touches the bottom of the screen then end the game
  if (ballLocation[1] + ballDelta[1] + ballRadius > canvas.height){
    endGame();
  }
  // If side of ball touches either side of the wall then reverse X direction
  //left of ball moves too far left
  if ((ballLocation[0] + ballDelta[0] - ballRadius < 0) ||
      //or right side of ball moves too far right
      (ballLocation[0] + ballDelta[0] + ballRadius > canvas.width)
      // or if ball collides in Y direction with bricks
      || ballCollideX()
     ){  
    ballDelta[0] = -ballDelta[0];
    // bouncingSound.play();
  }
  // if bottom of ball reaches the top of paddle,
  if (ballLocation[1] + ballDelta[1] + ballRadius >= paddleLocation[1]){
    // and it is positioned between the two ends of the paddle (is on top)
    if (ballLocation[0] + ballDelta[0] >= paddleLocation[0] && 
        ballLocation[0] + ballDelta[0] <= paddleLocation[0] + paddleSize[0]){
      ballDelta[1] = - ballDelta[1];
      // bouncingSound.play();
    }
  }
  
  // Move the ball
  ballLocation[0] += ballDelta[0];
  ballLocation[1] += ballDelta[1];
}
        
function movePaddle(){
  if (paddleMove == 'LEFT'){
    paddleDelta[0] = -paddleSpeed;
  } else if (paddleMove == 'RIGHT'){
    paddleDelta[0] = paddleSpeed;
  } else {
    paddleDelta[0] = 0;
  }
  // If paddle reaches the ends, then don't let it move 
  if (paddleLocation[0] + paddleDelta[0] < 0 || paddleLocation[0] + paddleDelta[0] + paddleSize[0] > canvas.width){
    paddleDelta[0] = 0; 
  }
  paddleLocation[0] += paddleDelta[0];
}

function randomRGB() {
  return 'rgb(' + Math.floor((Math.random() * 255) + 1) + ', ' + Math.floor((Math.random() * 255) + 1) + ', ' + Math.floor((Math.random() * 255) + 1) + ')';
}
        
function renderBall() {
  // Context.beginPath when you draw primitive shapes
  context.beginPath();
  context.arc(ballLocation[0], ballLocation[1], ballRadius, 0, Math.PI*2, true); // From 0 to 2xPI radians (full circle)
  context.fill(); // Fill up the path that you just drew	
}

function renderBrick(x, y, t) {
  if(t > 0) {
    context.fillStyle = renderBrickColors[x, y];
    context.fillRect(x * brickSize[0], y * brickSize[1], brickSize[0], brickSize[1]);
    // Also draw blackish border around the brick
    context.strokeRect(x * brickSize[0] + 1, y * brickSize[1] + 1, brickSize[0] - 2, brickSize[1] - 2);
  } else {
    context.clearRect(x * brickSize[0], y * brickSize[1], brickSize[0], brickSize[1]);
  }
}
        
function renderBrickColors() {
  if(brickColors == 0) {
    brickColors = bricks;
    for (var i = 0; i < bricks.length; i++) {
      for (var j = 0; j < bricks[i].length; j++) {
        brickColors[i, j] = randomRGB();
      }
    }
  }
  return brickColors;
}

function renderBricks() {
  for (var i = 0; i < bricks.length; i++) {
    for (var j = 0; j < bricks[i].length; j++) {
      renderBrick(j, i, bricks[i][j]);
    }
  }
}

function renderPaddle() {
  context.fillRect(paddleLocation[0], paddleLocation[1], paddleSize[0], paddleSize[1]); 
}
        
function renderScore() {
  //Set the text font and color
  context.fillStyle = 'rgb(50,100,50)';
  context.font = "20px Times New Roman";
  //Clear the bottom 30 pixels of the canvas
  context.clearRect(0, canvas.height - scoreHeight, canvas.width, scoreHeight);	
  // Write Text 5 pixels from the bottom of the canvas
  context.fillText('Score: ' + score, 10, canvas.height - 5);
}
        
function startGame(){
  ballDelta[1] = -4;
  ballDelta[0] = -2;
  paddleMove = 'NONE';
  paddleDelta[0] = 0;
  brickColors = 0;
  initVars();
  // call the animate() function every 200ms until clearInterval(gameLoop) is called
  gameLoop = setInterval(animate,20);
}
var doThis = function(){
  $(function() {
    canvas = $('#canvas');
    context = canvas.getContext("2d");
    // Start Tracking Keystokes
    $(document).keydown(function(e) {
      switch(e.which) {
        case $.ui.keyCode.LEFT:
          paddleMove = 'LEFT';
          break;
          
        case $.ui.keyCode.UP:
          startGame();
          break;
          
        case $.ui.keyCode.RIGHT:
          paddleMove = 'RIGHT';
          break;
          
        default: return; // allow other keys to be handled
      };
      // prevent default action (eg. page moving up/down)
      // but consider accessibility (eg. user may want to use keys to choose a radio button)
      e.preventDefault();
    });
    
    $(document).keyup(function(e) {
      switch(e.which) {
        case $.ui.keyCode.LEFT:
          paddleMove = 'NONE';
          break;
        case $.ui.keyCode.RIGHT:
          paddleMove = 'NONE';
          break;
        default: return; // allow other keys to be handled
      }
      // prevent default action (eg. page moving up/down)
      // but consider accessibility (eg. user may want to use keys to choose a radio button)
      e.preventDefault();
    });
  };
};

getJQuery(doThis);
